package com.logInterceptor.service;

import com.logInterceptor.model.AuditLog;
import com.logInterceptor.model.Auditable;
import org.hibernate.EmptyInterceptor;
import org.hibernate.Session;
import org.hibernate.type.Type;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Iterator;

import java.util.Set;

public class AuditLogInterceptor extends EmptyInterceptor implements Serializable {

    private Session session;
    private Set inserts = new HashSet();
    private Set updates = new HashSet();

    public void setSession(Session session) {
        this.session = session;
    }
    public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        System.out.println("==================onDelete====================");
    }

    public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState,
                                Object[] previousState, String[] propertyNames, Type[] types) {
        System.out.println("==================onFlushDirty====================");
        if (entity instanceof Auditable) {
            updates.add(entity);
        }
        return false;
    }

    public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        System.out.println("==================onLoad====================");
        return false;
    }

    public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        System.out.println("==================onSave====================");
        if (entity instanceof Auditable) {
            inserts.add(entity);
        }
        return false;
    }

    public void postFlush(Iterator entities) {
        System.out.println("==================postFlush====================");
        try {
            Iterator it = updates.iterator();
            while (it.hasNext()) {
                Auditable entity = (Auditable) it.next();
                AuditLog.logEvent("update", entity, session);
            }
            it = inserts.iterator();
            while (it.hasNext()) {
                Auditable entity = (Auditable) it.next();
                AuditLog.logEvent("insert", entity, session);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            inserts.clear();
            updates.clear();
        }
    }

    public void preFlush(Iterator entities) {
    }
    public Object instantiate(Class clazz, Serializable id) {
        return null;
    }

    public int[] findDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState,
                           String[] propertyNames, Type[] types) {
        return null;
    }

    public Boolean isUnsaved(Object entity) {
        return null;
    }
}
